package com.mm.org.n3r.idworker.utils;

import static java.io.File.separator;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.mm.org.n3r.idworker.utils.Serializes.closeQuietly;

public class Props {
	static Logger log = LoggerFactory.getLogger(Props.class);

	public static Properties tryProperties(String propertiesFileName, String userHomeBasePath) {
		Properties properties = new Properties();
		InputStream is = null;
		try {
			is = Props.tryResource(propertiesFileName, userHomeBasePath, Silent.ON);
			if (is != null)
				properties.load(is);
		} catch (IOException e) {
			log.error("load properties error: {}", e.getMessage());
		} finally {
			closeQuietly(is);
		}

		return properties;
	}

	enum Silent {
		ON, OFF
	}

	public static InputStream tryResource(String propertiesFileName, String userHomeBasePath, Silent silent) {
		InputStream is = currentDirResource(new File(propertiesFileName));
		if (is != null)
			return is;

		is = userHomeResource(propertiesFileName, userHomeBasePath);
		if (is != null)
			return is;

		is = classpathResource(propertiesFileName);
		if (is != null || silent == Silent.ON)
			return is;

		throw new RuntimeException("fail to find " + propertiesFileName + " in current dir or classpath");
	}

	private static InputStream userHomeResource(String pathname, String appHome) {
		String filePath = System.getProperty("user.home") + separator + appHome;
		File dir = new File(filePath);
		if (!dir.exists())
			return null;

		return currentDirResource(new File(dir, pathname));
	}

	private static InputStream currentDirResource(File file) {
		if (!file.exists())
			return null;

		try {
			return new FileInputStream(file);
		} catch (FileNotFoundException e) {
			// This should not happened
			log.error("read file {} error", file, e);
			return null;
		}
	}

	public static InputStream classpathResource(String resourceName) {
		return Props.class.getClassLoader().getResourceAsStream(resourceName);
	}

}
